using AutoMapper;
using FeishuWorkflowService.Models;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;

namespace FeishuWorkflowService.Services
{
    public class FeishuService : IFeishuService
    {
        private readonly HttpClient _httpClient;
        private readonly ILogger<FeishuService> _logger;
        private readonly FeishuConfig _feishuConfig;
        private string _accessToken;
        private DateTime _tokenExpireTime = DateTime.MinValue;
        private readonly IMapper _mapper;

        public FeishuService(
            HttpClient httpClient,
            ILogger<FeishuService> logger,
            IOptions<FeishuConfig> feishuConfig,
            IMapper mapper)
        {
            _httpClient = httpClient;
            _logger = logger;
            _feishuConfig = feishuConfig.Value;
            _mapper = mapper;
        }

        /// <summary>
        /// 获取飞书访问令牌
        /// </summary>
        public async Task<string> GetAccessTokenAsync()
        {
            // 如果令牌未过期，直接返回
            if (!string.IsNullOrEmpty(_accessToken) && DateTime.Now < _tokenExpireTime)
            {
                return _accessToken;
            }

            try
            {
                var requestUrl = $"{_feishuConfig.BaseUrl}/auth/v3/tenant_access_token/internal";
                var requestBody = new
                {
                    app_id = _feishuConfig.AppId,
                    app_secret = _feishuConfig.AppSecret
                };

                var content = new StringContent(JsonConvert.SerializeObject(requestBody), Encoding.UTF8, "application/json");
                var response = await _httpClient.PostAsync(requestUrl, content);
                response.EnsureSuccessStatusCode();

                var responseContent = await response.Content.ReadAsStringAsync();
                var tokenResponse = JsonConvert.DeserializeObject<FeishuTokenResponse>(responseContent);

                if (tokenResponse?.Code == 0)
                {
                    _accessToken = tokenResponse.TenantAccessToken;
                    _tokenExpireTime = DateTime.Now.AddSeconds(tokenResponse.Expire - 60); // 提前60秒过期，避免边界问题
                    return _accessToken;
                }
                else
                {
                    _logger.LogError("获取飞书访问令牌失败: {Response}", responseContent);
                    throw new Exception($"获取飞书访问令牌失败: {tokenResponse?.Msg}");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取飞书访问令牌异常");
                throw;
            }
        }

        /// <summary>
        /// 创建审批流程实例
        /// </summary>
        public async Task<string> CreateWorkflowInstanceAsync(CreateWorkflowRequest request)
        {
            try
            {
                var accessToken = await GetAccessTokenAsync();

                var workflowTemplate = await GetWorkflowTemplateDetailAsync(request.ApprovalCode);
                var formData = Assignment(request.FormData, workflowTemplate.FormTemplateData);


                var requestUrl = $"{_feishuConfig.BaseUrl}/approval/v4/instances";

                var requestBody = new
                {
                    approval_code = request.ApprovalCode,
                    user_id = request.OperatorId,
                    form = JsonConvert.SerializeObject(formData)
                };

                var content = new StringContent(JsonConvert.SerializeObject(requestBody), Encoding.UTF8, "application/json");
                _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);

                var response = await _httpClient.PostAsync(requestUrl, content);
                response.EnsureSuccessStatusCode();

                var responseContent = await response.Content.ReadAsStringAsync();
                var workflowResponse = JsonConvert.DeserializeObject<FeishuWorkflowResponse>(responseContent.Replace("\\", ""));

                if (workflowResponse?.Code == 0)
                {
                    return workflowResponse.Data.Instance_code;
                }
                else
                {
                    _logger.LogError("创建飞书审批流程失败: {Response}", responseContent);
                    throw new Exception($"创建飞书审批流程失败: {workflowResponse?.Msg}");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建飞书审批流程异常");
                throw;
            }
        }

        /// <summary>
        /// 查询审批流程状态
        /// </summary>
        public async Task<WorkflowStatus> GetWorkflowStatusAsync(string instanceId)
        {
            try
            {
                var accessToken = await GetAccessTokenAsync();
                var requestUrl = $"{_feishuConfig.BaseUrl}/approval/v4/instances/{instanceId}";

                _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                var response = await _httpClient.GetAsync(requestUrl);
                response.EnsureSuccessStatusCode();

                var responseContent = await response.Content.ReadAsStringAsync();

                var statusResponse = JsonConvert.DeserializeObject<FeishuWorkflowStatusResponse>(responseContent);

                if (statusResponse?.Code == 0)
                {
                    return new WorkflowStatus
                    {
                        InstanceId = statusResponse.Data.Instance_code,
                        Status = statusResponse.Data.Status,
                        ApprovalCode = statusResponse.Data.Approval_code,
                        //Title = statusResponse.Data.Title,
                        FormData = statusResponse.Data.Form,
                        Serialnumber = statusResponse.Data.Serial_number
                    };
                }
                else
                {
                    _logger.LogError("查询飞书审批流程状态失败: {Response}", responseContent);
                    throw new Exception($"查询飞书审批流程状态失败: {statusResponse?.Msg}");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询飞书审批流程状态异常");
                throw;
            }
        }


        /// <summary>
        /// 验证回调签名
        /// </summary>
        public bool VerifySignature(string timestamp, string nonce, string signature)
        {
            try
            {
                // 按照飞书文档要求，将timestamp、nonce和token按字典序排序后拼接
                var token = _feishuConfig.AppSecret; // 使用AppSecret作为验证Token
                var array = new[] { timestamp, nonce, token }.OrderBy(x => x).ToArray();
                var str = string.Join("", array);

                // 使用SHA1算法计算签名
                using (var sha1 = SHA1.Create())
                {
                    var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(str));
                    var calculatedSignature = BitConverter.ToString(hash).Replace("-", "").ToLower();

                    // 比较计算的签名和传入的签名
                    return calculatedSignature == signature.ToLower();
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "验证飞书回调签名异常");
                return false;
            }
        }

        /// <summary>
        /// 获取工作流模板详情
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<WorkflowTemplate> GetWorkflowTemplateDetailAsync(string ApprovalTemplateNode)
        {
            try
            {
                var accessToken = await GetAccessTokenAsync();
                var requestUrl = $"{_feishuConfig.BaseUrl}/approval/v4/approvals/{ApprovalTemplateNode}";

                _httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
                var response = await _httpClient.GetAsync(requestUrl);
                response.EnsureSuccessStatusCode();

                var responseContent = await response.Content.ReadAsStringAsync();
                var workflowTemplateRepose = JsonConvert.DeserializeObject<FeishuWorkflowTemplateResponse>(responseContent);
                

                if (workflowTemplateRepose?.Code == 0)
                {
                    return new WorkflowTemplate
                    {
                        ApprovalTemplateName = workflowTemplateRepose.Data.Approval_name,
                        ApprovalTemplateNode = ApprovalTemplateNode,
                        FormTemplateData = ConvertFormTemplateData(workflowTemplateRepose.Data.Form)
                    };

                }
                else
                {
                    _logger.LogError("查询飞书审批流程状态失败: {Response}", responseContent);
                    throw new Exception($"查询飞书审批流程状态失败: {workflowTemplateRepose?.Msg}");
                }
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "查询飞书审批流程状态异常");
                throw;
            }
        }

        private List<Widget> ConvertFormTemplateData(string form)
        {
            var ret = new List<FormItem?>();
            var widgets =  JsonConvert.DeserializeObject<List<Widget>>(form);

            
            return widgets;
        }

        /// <summary>
        /// 赋值 (接口传参按照模板配置赋值)
        /// </summary>
        /// <param name="FormData"></param>
        /// <param name="template"></param>
        /// <returns></returns>
        private List<FormItem?>? Assignment(Dictionary<string, object>? requestformData , List<Widget>? template)
        {
            var ret = new List<FormItem?>();
            if (requestformData == null || !requestformData.Any()) return ret;
            foreach (var materialDict in requestformData)
            {
                if (template.Select(e => e.custom_id).Contains(materialDict.Key))
                {
                    var _widget = template.FirstOrDefault(e => e.custom_id == materialDict.Key);
                    if (_widget.type == "input" || _widget.type == "textarea" || _widget.type == "date" || _widget.type == "number")
                    {
                        var _ = _mapper.Map<FormItem?>(_widget);
                        _.value = materialDict.Value;
                        ret.Add(_);
                    }
                    if (_widget.type == "dateInterval")
                    {
                        var _ = _mapper.Map<FormItem?>(_widget);
                        _.value = materialDict.Value;
                        ret.Add(_);
                    }

                    if (_widget.type == "fieldList")
                    {
                        var _ = _mapper.Map<FormItem?>(_widget);
                        var _children = new List<List<FormItem>>();
                        
                        foreach (var item in JsonConvert.DeserializeObject<List<Dictionary<string,object?>>>(JsonConvert.SerializeObject(materialDict.Value)))
                        {
                            _children.Add(Assignment(item, _widget.children));
                        }
                        _.value = _children;
                        ret.Add(_);
                    }
                }

            }

            return ret;
        }
    }
}